package cn.wolfcode.p2p.business.service.impl;

import cn.wolfcode.p2p.business.domain.BidRequest;
import cn.wolfcode.p2p.business.domain.PaymentSchedule;
import cn.wolfcode.p2p.business.mapper.PaymentScheduleMapper;
import cn.wolfcode.p2p.business.query.PaymentScheduleQuery;
import cn.wolfcode.p2p.business.service.IPaymentScheduleDetailService;
import cn.wolfcode.p2p.business.service.IPaymentScheduleService;
import cn.wolfcode.p2p.util.CalculatetUtil;
import cn.wolfcode.p2p.util.Constants;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class PaymentScheduleServiceImpl implements IPaymentScheduleService {
    @Autowired
    private PaymentScheduleMapper paymentScheduleMapper;
    @Autowired
    private IPaymentScheduleDetailService paymentScheduleDetailService;

    @Override
    public List<PaymentSchedule> createPaymentSchedule(BidRequest br) {
        //总期数
        int monthIndexs = br.getMonthes2Return();
        //还款开始时间,使用发标时间
        Date beginDate = br.getPublishTime();
        BigDecimal totalInterest = Constants.ZERO;
        BigDecimal totalPrincipal = Constants.ZERO;
        List<PaymentSchedule> pss = new ArrayList<>();
        for (int i = 0; i < monthIndexs; i++) {
            PaymentSchedule ps = new PaymentSchedule();
            ps.setBidRequestId(br.getId());
            ps.setBidRequestTitle(br.getTitle());
            ps.setBorrowUser(br.getCreateUser());
            ps.setDeadLine(DateUtils.addMonths(beginDate, i + 1));
            ps.setMonthIndex(i + 1);
            ps.setState(Constants.PAYMENT_STATE_NORMAL);
            ps.setBidRequestType(br.getReturnType());
            ps.setReturnType(br.getReturnType());
            /*
            判断是否是最后一期, 如果不是,使用正常还款工具计算,如果是使用
              借款总额- 非最后一期的总本金 = 最后一期的本金
              借款总利息 - 非最后一期收款的总利息 = 最后一期的利息
              注意:以上设计最后一期,是为了解决计算精度问题导致的数据上会略有所差
            */
            if (i == monthIndexs - 1) {
                ps.setPrincipal(br.getBidRequestAmount().subtract(totalPrincipal));
                ps.setInterest(br.getTotalRewardAmount().subtract(totalInterest));
                ps.setTotalAmount(ps.getInterest().add(ps.getPrincipal()));
            } else {
                //计算本期还款金额
                BigDecimal monthToReturnMoney = CalculatetUtil.calMonthToReturnMoney(ps.getReturnType(), br.getBidRequestAmount(), br.getCurrentRate(), i + 1, br.getMonthes2Return());
                ps.setTotalAmount(monthToReturnMoney.setScale(Constants.STORE_SCALE, RoundingMode.HALF_UP));
                //计算本期还款利息
                BigDecimal monthlyInterest = CalculatetUtil.calMonthlyInterest(ps.getReturnType(), br.getBidRequestAmount(), br.getCurrentRate(), i + 1, br.getMonthes2Return());
                ps.setInterest(monthlyInterest.setScale(Constants.STORE_SCALE, RoundingMode.HALF_UP));
                ps.setPrincipal(ps.getTotalAmount().subtract(ps.getInterest()));
                totalInterest = totalInterest.add(ps.getInterest());
                totalPrincipal = totalPrincipal.add(ps.getPrincipal());
            }
            paymentScheduleMapper.insert(ps);
            pss.add(ps);
            //创建本期还款计划对应的收款计划
            paymentScheduleDetailService.createPaymentScheduleDetail(ps, br);
        }
        return pss;
    }

    @Override
    public PageInfo query(PaymentScheduleQuery qo) {
        PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
        List<PaymentSchedule> list = paymentScheduleMapper.selectForList(qo);
        return new PageInfo(list);
    }

    @Override
    public PaymentSchedule getById(Long id) {
        return paymentScheduleMapper.selectByPrimaryKey(id);
    }

    @Override
    public void update(PaymentSchedule ps) {
        paymentScheduleMapper.updateByPrimaryKey(ps);
    }

    @Override
    public int getReturnSuccessMonthIndexNumber(Long bidRequestId, int state) {
        return paymentScheduleMapper.getReturnSuccessMonthIndexNumber(bidRequestId, state);
    }
}
